/**
 * @author Fang Lu, fanglupku@gmail.com
 * 2011-4-19
 */
package data.processor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import util.FileDealer;

public class ExceptionExtractor {
	private static Pattern stackInfoPattern;
	static{
		String strStackInfoPattern = "at\\s+[^\\u0028\\s]+\\s*\\u0028[^\\u0029]+\\u0029";
		stackInfoPattern = Pattern.compile(strStackInfoPattern, Pattern.CASE_INSENSITIVE);
	}
//	private static ArrayList<Pattern> exceptionStackPattern;
//	private static String strSimpleClassNamePattern = "[a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*";
//	private static String strFullClassNamePattern = "([a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*)(\\u002E([a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*))*";
//	private static String strFullMethodNamePattern = "([a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*)(\\u002E([a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*))*"
//								+ "(\\u002E<([a-zA-Z_\\u0024][a-zA-Z0-9_\\u0024]*)>)*";
//	static {
//		exceptionStackPattern = new ArrayList<Pattern>();
//		String s1 = "\\s*at\\s+?" + strFullMethodNamePattern
//				+ "\\s*?\\u0028\\s*?(\\s*?(" + strSimpleClassNamePattern 
//				+ ".java\\s*?.\\s*?\\d+?)|(native method)|(unknown source)|(<generated>)\\s*?)" 
//				+ "\\s*?\\u0029";
//		s1 = "(" + s1 + "\\s*)+(\\s*(\\u002E)+\\s+\\d+\\s+more\\s*){0,1}"; 
//		Pattern p1 = Pattern.compile(s1, Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
//		exceptionStackPattern.add(p1);
//	}
	
	public static void main(String args[]){
		try {
//			String content = FileDealer.getFileContent("C:/Users/ftc/Desktop/Exceptions/Exceptions/012.txt");
//			content = content.replaceAll("<", "&lt;");
//			content = content.replaceAll(">", "&gt;");
			
			String content = FileDealer.getFileContent("C:/Users/ftc/Desktop/viewtopic.php");
			String text = PageContentExtractor.extractTextFromPage(content, 0);
//			System.out.println(text);
			ArrayList<String> exceptionList =  getExceptionList(text);
			System.out.println(exceptionList.size());
			for (int i=0; i<exceptionList.size(); ++i){
				System.out.println(i+ ":" + exceptionList.get(i));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static String getExceptionTitle(String firstPart){
		int lastEndLine = firstPart.lastIndexOf("\n");
		if (lastEndLine < 0){
			return firstPart;
		}
		String lastLine = new String(firstPart.substring(lastEndLine, firstPart.length()));
		return lastLine;
	}
	
	public static ArrayList<String> getExceptionList(String content){
		ArrayList<String> exceptionList = new ArrayList<String>();
		StringReader sr = new StringReader(content);
		BufferedReader br = new BufferedReader(sr);
		
		try {
			String oneLine = br.readLine();
			String lastLine = "";
			boolean isLastLineStackInfo = false;
			StringBuffer sb = new StringBuffer();
			while (oneLine != null){
				oneLine = oneLine.trim();
				if (oneLine.length() == 0){
					oneLine = br.readLine();
					continue;
				}
				Matcher matcher = stackInfoPattern.matcher(oneLine);
				boolean isThisLineStackInfo = false;
				boolean isFirstInLine = true;
				while (matcher.find()){
					if (isLastLineStackInfo == false){
						String prefix = "";
						if (matcher.start() > 0){
							prefix = new String(oneLine.substring(0, matcher.start())).toLowerCase();
						}
						if (prefix.indexOf("exception") >= 0){
							sb.append(prefix);
							sb.append("\n");
							String thisStackInfo = new String(oneLine.substring(matcher.start(), matcher.end()));
							sb.append("\t");
							sb.append(thisStackInfo);
							sb.append("\n");
							isThisLineStackInfo = true;
						}else if (lastLine.toLowerCase().indexOf("exception") >= 0 && isFirstInLine == true){
							sb.append(lastLine);
							sb.append("\n");
							String thisStackInfo = new String(oneLine.substring(matcher.start(), matcher.end()));
							sb.append("\t");
							sb.append(thisStackInfo);
							sb.append("\n");
							isThisLineStackInfo = true;
						}else{
							isThisLineStackInfo = false;
							break;
						}
					}else{
						String thisStackInfo = new String(oneLine.substring(matcher.start(), matcher.end()));
						sb.append("\t");
						sb.append(thisStackInfo);
						sb.append("\n");
						isThisLineStackInfo = true;
					}
					isFirstInLine = false;
				}
				if (isThisLineStackInfo == false && sb.length() > 0){
					
					exceptionList.add(sb.toString());
					sb.delete(0, sb.length());
				}
				isLastLineStackInfo = isThisLineStackInfo;
				lastLine = oneLine;
				oneLine = br.readLine();
			}
			if (sb.length() > 0){
				exceptionList.add(sb.toString());
				sb.delete(0, sb.length());
			}
			
			br.close();
			sr.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
//		for (int i=0; i<exceptionStackPattern.size(); ++i){
//			Matcher matcher = exceptionStackPattern.get(i).matcher(content);
//			while(matcher.find()){
//				String thisException = new String(content.substring(matcher.start(),matcher.end()));
//				String firstPart = new String(content.substring(0, matcher.start()));
//				thisException = getExceptionTitle(firstPart) + thisException;
//				exceptionList.add(thisException);
//			}
//		}
		return exceptionList;
	}
}
